package com.github.llyb120.qiuya.storage;

import com.github.llyb120.qiuya.error.InvalidDataException;
import com.github.llyb120.qiuya.type.QCollectionMeta;
import com.github.llyb120.qiuya.type.QString;

import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import static com.github.llyb120.qiuya.storage.bptree.BPlusTree.INVALID_OFFSET;

public class Qiu {

    public VirtualFile vf;

    //校验串
    private static final byte[] Sign = "qiuya".getBytes();

    /**
     * 各个区块偏移
     */
    //校验位置
    private static final long OFFSET_SIGN = 0;
    //当前长度位置
    private static final long OFFSET_CURRENT_LENGTH = Sign.length;
    //表名信息位置
    private static final long OFFSET_COLLECTION_METADATA = OFFSET_CURRENT_LENGTH + Long.BYTES;
    //索引空块起始偏移，最大支持
    private static long OFFSET_INDEX_FREE_BLOCKS;
    //数据区
    private static long OFFSET_DATA;

    /**
     * 数据库配置
     */
    //最大支持表个数
    private static final int MAX_COLLECTION = 1000;
    //最大表头所占空间
    private static int MAX_TABLE_HEAD_SIZE;
    //最长表名
    private static final int MAX_COLLECTION_NAME_LENGTH = 100;
    //最大索引空块 1000
    private static final int MAX_INDEX_FREE_BLOCK = 1000;

    //最大索引空块所占空间(10M)
    private static final int MAX_INDEX_FREE_BLOCK_SIZE = 1024 * 1024 * 10;
    static {
        MAX_TABLE_HEAD_SIZE = QCollectionMeta.maxLen(MAX_COLLECTION, MAX_COLLECTION_NAME_LENGTH);//MAX_TABLE_HEAD * (Integer.BYTES + MAX_TABLE_NAME_LENGTH + Long.BYTES);
        OFFSET_INDEX_FREE_BLOCKS = OFFSET_COLLECTION_METADATA + MAX_TABLE_HEAD_SIZE;
    }

    private QCollectionMeta colMeta;

    //文件偏移
    private long fileOffset = 0;

    public Qiu(File file){
        vf = new VirtualFile(file);
        //
        init();
    }

    void init(){
        if(!vf.isNew()){
             if(!checkSign()) {
                 throw new InvalidDataException();
             }
        } else {
            vf.writeBytes(OFFSET_SIGN, Sign);
        }
        //读取表头
        colMeta = new QCollectionMeta(this, OFFSET_COLLECTION_METADATA, MAX_COLLECTION, MAX_COLLECTION_NAME_LENGTH, vf.isNew());
//        colMeta.put("fuck", INVALID_OFFSET);
//        colMeta.flush();
//        int d = 2;
    }

//    void loadTableInfos(){
//        int singleNameLength = Integer.BYTES + MAX_TABLE_NAME_LENGTH + Long.BYTES;
//        for (long i = OFFSET_TABLE_HEAD; i < OFFSET_INDEX_FREE_BLOCKS; i += singleNameLength) {
//            int len = vf.readInt(i);
//            if (len == 0) {
//                break;
//            }
//            String str = vf.readString(i + Integer.BYTES, len);
//            long offset = vf.readLong(i + Integer.BYTES + MAX_TABLE_NAME_LENGTH);
//            tableOffsetMap.put(str, offset);
//        }
//    }

    boolean checkSign(){
        byte[] bs = vf.readBytes(0, Sign.length);
        return Arrays.equals(bs, Sign);
    }
}
